#ifndef _GENETATE_CODE_H
#define _GENETATE_CODE_H

#include <hash_map>
#include "findInTable.h"
#include "semantic.h"
#include "JavaDefines.h"
using namespace std;

extern void initStmt(struct StmtInfo* stmt);
extern void initExpr(struct ExprInfo* expr);

#define OPERAND_STACK_SIZE 2048

union u4{
    char bytes[4];
    unsigned long int number;
};

union s4{
    signed char bytes[4];
    signed long int number;
};

void writeS4(std::string* data, long int number);
void writeS4(std::string* data, long int number,int pos);
void generateCode(char* filename);
void createClassFile(struct ClassInfo_Element Class);
void generateCodeForConstsTable(std::string* data,ConstTable Consts);
void generateCodeForConst(std::string* data,struct ConstInfo_Element Const);
void generateCodeForFieldsTable(std::string* data,FieldTable Fields,ConstTable Consts);
void generateCodeForField(std::string* data,struct FieldInfo_Element Field,ConstTable Consts);
void generateCodeForMethodsTable(std::string* data,MethodsTable Methods,ConstTable Consts);
void generateCodeForMethod(std::string* data,struct MethodInfo_Element Method,ConstTable Consts);
void generatreCodeForMethodAttributes(std::string* data,struct MethodInfo_Element Method,ConstTable Consts);
void generateCodeAttributeForMethod(std::string* data,struct MethodInfo_Element Method,ConstTable Consts);
void generateByteCodeForMethod(std::string* data,struct MethodInfo_Element Method);
void generateByteCodeForStmt(std::string* data,struct StmtInfo* stmt);
void generateByteCodeForExpr(std::string* data, struct ExprInfo* expr);

void generateCodeForArray(std::string* data,struct ArrMemListInfo* elements);

void generateByteCodeForIf(std::string* data, struct IfStmtInfo* pIfStmt);
void generateByteCodeForCycleWhile(std::string* data,struct StmtInfo* pWhile);
void generateByteCodeForCycleDoWhile(std::string* data,struct StmtInfo* pDoWhile);
void generateByteCodeForCycleFor(std::string* data,struct StmtInfo* pFor);
void generateByteCodeForReturn(std::string* data,struct StmtInfo* pStmt);
void generateByteCodeForSwitch(std::string* data,struct SwitchStmtInfo* pStmt);

void generateByteCodeForContructor(std::string* data,struct MethodInfo_Element Method);

int generateByteCodeForCaseStmtList(std::string* data, struct StmtListInfo* pList);



#endif